home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / C / Applications / µSim 1.1 / FabLibsƒ / StdGetFolder.c < prev    next >
Encoding:
Text File  |  1997-02-10  |  7.5 KB  |  295 lines  |  [TEXT/CWIE]

  1. /*
  2. Copyright © 1993,1994 by Fabrizio Oddone
  3. ••• ••• ••• ••• ••• ••• ••• ••• ••• •••
  4. This source code is distributed as freeware: you can copy, exchange, modify this
  5. code as you wish. You may include this code in any kind of application: freeware,
  6. shareware, or commercial, provided that full credits are given.
  7. You may not sell or distribute this code for profit.
  8. */
  9.  
  10. /* I did not write the code in this file; I took it from some sample code
  11. from Apple, I think.
  12. I modified the original code a little bit, though. */
  13.  
  14. //#pragma load "MacDump"
  15. #ifndef __MOREFILESEXTRAS__
  16. #include <MoreFilesExtras.h>
  17. #endif
  18. #ifndef __FSPCOMPAT__
  19. #include <FSpCompat.h>
  20. #endif
  21.  
  22.  
  23. #include    "UtilsSys7.h"
  24. #include    "Independents.h"
  25.  
  26. #include    "StdGetFolder.h"
  27.  
  28. /* typedefs */
  29.  
  30. typedef struct {
  31.     StandardFileReply *replyPtr;
  32.     void (*updateProc)(EventRecord *);
  33.     void (*activateProc)(EventRecord *);
  34.     FSSpec oldSelection;
  35.     short    SelectStrRsrc;
  36. //    short    DeskStrRsrc;
  37. } SFData, *SFDataPtr;
  38.  
  39. /* prototypes */
  40.  
  41. static pascal short MyDlgHook(short item, DialogPtr theDlg, SFDataPtr sfp);
  42. static pascal Boolean MyModalFilter(DialogPtr theDlg, EventRecord *ev, short *itemHit, SFDataPtr myData);
  43. //static pascal Boolean FilterAllFiles(CInfoPBPtr pb, Ptr myDataPtr);
  44. static void SetSelectButtonName(ConstStr255Param selName, const DialogPtr theDlg, short, Boolean);
  45. static Boolean SameFile(const FSSpecPtr file1, const FSSpecPtr file2);
  46. static OSErr GetDeskFolderSpec(FSSpecPtr, short vRefNum);
  47. static OSErr MakeCanonFSSpec(FSSpecPtr);
  48. static Boolean ShouldHiliteSelect(FSSpecPtr);
  49.  
  50. /* constants */
  51.  
  52. #define    kSelectItem            10
  53. #define    kCanSelectDesktop    true
  54. #define    kSelectKey            's'
  55.  
  56. /* globals */
  57.  
  58. Boolean    gHasFindFolder;
  59. FSSpec    gDeskFolderSpec;
  60.  
  61. /*
  62.     strHndl = GetString(kSelectStrRsrc);
  63.     strHndl = GetString(kDeskStrRsrc);
  64. */
  65.  
  66. /* do getfile */
  67.  
  68. Boolean CustomGet(FSSpec *fSpec,
  69.                 void (*DoUpdate)(EventRecord *),
  70.                 void (*DoActivate)(EventRecord *),
  71.                 short SFDlgID, short SelectStrRsrc/*, short DeskStrRsrc*/)
  72. {
  73. //FileFilterYDUPP    FilterAllFilesUPP = NewFileFilterYDProc(FilterAllFiles);
  74. DlgHookYDUPP    MyDlgHookUPP = NewDlgHookYDProc(MyDlgHook);
  75. ModalFilterYDUPP    MyModalFilterUPP = NewModalFilterYDProc(MyModalFilter);
  76. Point    where = {-1,-1};
  77. OSType    myType = 'ƒldr';
  78. StandardFileReply    sfReply;
  79. SFData    sfUserData;
  80. Boolean    targetIsFolder, wasAliased;
  81.  
  82. /* initialize user data area */
  83.  
  84. sfUserData.replyPtr = &sfReply;
  85. sfUserData.updateProc = DoUpdate;
  86. sfUserData.activateProc = DoActivate;
  87. sfUserData.oldSelection.vRefNum = -9999;    /* init to ridiculous value */
  88. sfUserData.SelectStrRsrc = SelectStrRsrc;
  89. //sfUserData.DeskStrRsrc = DeskStrRsrc;
  90.  
  91. CustomGetFile(nil, 1, &myType, &sfReply, SFDlgID, where, MyDlgHookUPP,
  92.                 MyModalFilterUPP, nil, nil, &sfUserData);
  93.  
  94. if (sfReply.sfGood) {
  95.     if (ResolveAliasFile(&sfReply.sfFile, true, &targetIsFolder, &wasAliased)) {
  96.         sfReply.sfGood = false;
  97.         }
  98.     else if (StrLength(sfReply.sfFile.name) == 0) {
  99.         (void) FSMakeFSSpecCompat(sfReply.sfFile.vRefNum, sfReply.sfFile.parID, nil, fSpec);
  100. //        sfReply.sfGood = false;
  101.         }
  102.     else
  103.         *fSpec = sfReply.sfFile;
  104.     }
  105.  
  106. if (MyModalFilterUPP)
  107.     DisposeRoutineDescriptor(MyModalFilterUPP);
  108. if (MyDlgHookUPP)
  109.     DisposeRoutineDescriptor(MyDlgHookUPP);
  110. //if (FilterAllFilesUPP)
  111. //    DisposeRoutineDescriptor(FilterAllFilesUPP);
  112.  
  113. return sfReply.sfGood;
  114. }
  115.  
  116.  
  117. /*    this dialog hook checks the contents of the additional edit fields
  118.     when the user selects a file.  The focus of the dialog is changed if one
  119.     of the fields is out of range.Ptr userData
  120. */
  121.  
  122. pascal short MyDlgHook(short item, DialogPtr theDlg, SFDataPtr sfUserData)
  123. {
  124. FSSpec curSpec;
  125.  
  126. if (GetWRefCon(GetDialogWindow(theDlg)) == sfMainDialogRefCon) {    
  127. //    sfUserData = (SFDataPtr) userData;
  128.     
  129.     if (item != sfHookFirstCall && item != sfHookLastCall) {
  130. /*        if (item == sfItemVolumeUser) {
  131.             sfUserData->replyPtr->sfFile.name[0] = '\0';
  132.             sfUserData->replyPtr->sfFile.parID = fsRtDirID;
  133.             sfUserData->replyPtr->sfIsFolder = false;
  134.             sfUserData->replyPtr->sfIsVolume = false;
  135.             sfUserData->replyPtr->sfFlags = 0;
  136.             item = sfHookChangeSelection;
  137.             }
  138. */
  139.         if (!SameFile(&sfUserData->replyPtr->sfFile, &sfUserData->oldSelection)) {
  140.             curSpec = sfUserData->replyPtr->sfFile;
  141.             (void)MakeCanonFSSpec(&curSpec);
  142.             
  143.             if (curSpec.vRefNum != sfUserData->oldSelection.vRefNum)
  144.                 GetDeskFolderSpec(&gDeskFolderSpec, curSpec.vRefNum);    
  145.             SetSelectButtonName(curSpec.name, theDlg, sfUserData->SelectStrRsrc, ShouldHiliteSelect(&curSpec));
  146.         
  147.             sfUserData->oldSelection = sfUserData->replyPtr->sfFile;
  148.             }
  149.  
  150.         if (item == kSelectItem)
  151.             item = sfItemOpenButton;
  152.         }
  153.     }
  154. return item;
  155. }
  156.  
  157.  
  158. pascal Boolean MyModalFilter(DialogPtr theDlg, EventRecord *ev, short *itemHit, SFDataPtr myData)
  159. {
  160. Boolean evHandled = false;
  161. char keyPressed;
  162.  
  163. if (GetWRefCon(GetDialogWindow(theDlg)) == sfMainDialogRefCon)
  164.     switch (ev->what) {
  165.         case keyDown:
  166.         case autoKey:
  167.             keyPressed = CHARFROMMESSAGE(ev->message);
  168.             if (ev->modifiers & cmdKey) {
  169.                 switch (keyPressed) {
  170.                     case kSelectKey:
  171.                         FlashButton(theDlg, kSelectItem);
  172.                         *itemHit = kSelectItem;
  173.                         evHandled = true;
  174.                         break;
  175.                 }
  176.             }
  177.             break;
  178.         case updateEvt:
  179.             if (theDlg != (DialogPtr)ev->message && myData->updateProc) {
  180.                 myData->updateProc(ev);
  181.                 evHandled = true;
  182.                 }
  183.             break;
  184.         case activateEvt:
  185.             if (theDlg != (DialogPtr)ev->message && myData->activateProc) {
  186.                 myData->activateProc(ev);
  187.                 evHandled = true;
  188.                 }
  189.             break;
  190.         }
  191.  
  192. return evHandled;
  193. }
  194.  
  195. /*
  196. pascal Boolean FilterAllFiles(CInfoPBPtr pb, Ptr myDataPtr)
  197. {
  198. return ((pb->hFileInfo.ioFlAttrib & (1 << 4)) == 0);
  199. }
  200. */
  201.  
  202. void SetSelectButtonName(ConstStr255Param selName, const DialogPtr theDlg, short SelectStrRsrc, Boolean hilited)
  203. {
  204. Str63    storeName, tempLenStr, tempSelName;
  205. Rect    iRect;
  206. StringHandle    theString;
  207. Handle    iHndl;
  208. short    iType;
  209.  
  210. (void) PLstrcpy(tempSelName, selName);
  211. GetDialogItem(theDlg, kSelectItem, &iType, &iHndl, &iRect);
  212.  
  213. /* truncate select name to fit in button */
  214.  
  215. theString = GetString(SelectStrRsrc);
  216.  
  217. (void) PLstrcpy(tempLenStr, *theString);
  218.  
  219. PLstrcat(tempLenStr, "\p “”  ");
  220. TruncString(iRect.right - iRect.left - StringWidth(tempLenStr), tempSelName, smTruncMiddle);
  221.  
  222. (void) PLstrcpy(storeName, *theString);
  223. PLstrcat(storeName, "\p “");
  224. PLstrcat(storeName, tempSelName);
  225. PLstrcat(storeName, "\p”");
  226.  
  227. SetControlTitle((ControlHandle)iHndl, storeName);
  228.  
  229. //SetDItem(theDlg,kSelectItem,iType,iHndl,&iRect);
  230.  
  231. HiliteControl((ControlHandle)iHndl, hilited ? 0 : 255);
  232. ValidRect(&iRect);
  233. }
  234.  
  235.  
  236. Boolean SameFile(const FSSpecPtr file1, const FSSpecPtr file2)
  237. {
  238. return ((file1->vRefNum == file2->vRefNum) &&
  239.         (file1->parID == file2->parID) &&
  240.         (EqualString(file1->name,file2->name,false,true)));
  241. }
  242.  
  243.  
  244. OSErr GetDeskFolderSpec(FSSpecPtr fSpec, short vRefNum)
  245. {
  246. register OSErr err = -1;
  247.  
  248. if (gHasFindFolder) {
  249.     StrLength(fSpec->name) = 0;
  250.     err = FindFolder(vRefNum, kDesktopFolderType, kDontCreateFolder,
  251.                         &fSpec->vRefNum,&fSpec->parID);
  252.     if (err == noErr)
  253.         err = MakeCanonFSSpec(fSpec);
  254.     }
  255. else
  256.     fSpec->vRefNum = -9999;
  257.  
  258. return err;
  259. }
  260.  
  261.  
  262. Boolean ShouldHiliteSelect(FSSpecPtr fSpec)
  263. {
  264. //StringHandle    strHndl;
  265.  
  266. if (CheckVolLock(nil, fSpec->vRefNum))
  267.     return false;
  268. else if (FSpCheckObjectLock(fSpec))
  269.     return false;
  270. else if (SameFile(fSpec, &gDeskFolderSpec)) {
  271. //    strHndl = GetString(DeskStrRsrc);
  272. //    (void) PLstrcpy(fSpec->name, *strHndl);
  273.     return kCanSelectDesktop;
  274.     }
  275. else
  276.     return true;
  277. }
  278.  
  279. OSErr MakeCanonFSSpec(FSSpecPtr fSpec)
  280. {
  281. DirInfo infoPB;
  282. OSErr err = noErr;
  283.  
  284. if (StrLength(fSpec->name) == 0) {
  285.     infoPB.ioNamePtr = fSpec->name;
  286.     infoPB.ioVRefNum = fSpec->vRefNum;
  287.     infoPB.ioDrDirID = fSpec->parID;
  288.     infoPB.ioFDirIndex = -1;
  289.     err = PBGetCatInfoSync((CInfoPBPtr)&infoPB);
  290.     fSpec->parID = infoPB.ioDrParID;
  291.     }
  292. return err;
  293. }
  294.  
  295.